#ifndef USER_PLUGIN_DUMMY
#define USER_PLUGIN_DUMMY
#include <iostream>
#include <string>
#include <map>
#include <stdio.h>
#include <stdlib.h>
#include "../../../libpland/lib/plugin.hpp"

#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <stdio.h>
#include <linux/soundcard.h>
#include <boost/thread.hpp>



using namespace std;


class CoreC_Echo : public UserC_Plugin
{
public:
	CoreC_Echo();
	~CoreC_Echo();
	void start();
	void stop();
	void load_queues(CoreC_DQueue * front ,CoreC_DQueue * back);
private:
	CoreC_DQueue *_front;
	CoreC_DQueue *_back;
	bool _running;

};

#endif


CoreC_Echo::CoreC_Echo()
{
	_running = false;
}

void CoreC_Echo::start()
{
	_running = true;
	CoreC_Data * pcm = NULL;
	CoreC_Settings * set = CoreC_Settings::Instance();
	short int old[4096];
	char* oldbuff = (char*)old;
	memset(old,0, sizeof(old));
	set->setSetting("stream.echo.decay", "0");
	set->setSetting("stream.echo.filter", "70");
	while(_running)
	{
		float decay = utill_to_int(set->getSetting("stream.echo.decay"))/100.0;
		float filter = utill_to_int(set->getSetting("stream.echo.filter"))/100.0;
		short int* samples;
		char* buff;
		pcm = _front->pop();
		samples = (short int*)pcm->get_data();
		buff = (char*)pcm->get_data();
		CoreC_Data_Header* header = pcm->get_header();
		uint size = header->_size;
		if(size < 0)
			continue;
		for(int i = 0; i < size/2; i++)
		{
			samples[i] += decay*old[i];
		}
		for(int i = size; i< sizeof(old); i++)
		{
			oldbuff[i- size] = oldbuff[i];
		}
		for(int i = 0; i< size; i++)
		{
			oldbuff[i+ sizeof(old) - size] = buff[i];
		}
		for(int i = 2; i< sizeof(old); i++)
		{
			 oldbuff[ i ] =filter * oldbuff [i ] + ( 1.0 - filter ) * oldbuff[ i-2 ];
		}
		_back->push(pcm);
	}
}

void CoreC_Echo::stop()
{
	_running = false;

}

void CoreC_Echo::load_queues(CoreC_DQueue* front ,CoreC_DQueue* back)
{
	_front  = front;
	_back  = back;
}


extern "C"
{
	UserC_Plugin* Core_GetInstance()
	{
		return new CoreC_Echo();
	}

	void Core_KillInstance(UserC_Plugin* a)
	{
		delete a;
	}
}
